
/******************************************************************************
 * MODULE     : language.hpp
 * DESCRIPTION: language specific features, which include
 *              - punctuation rules
 *              - hyphenation
 *              - (future) dictionary and grammar rumes for spell-checker
 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
 *******************************************************************************
 * This software falls under the GNU general public license version 3 or later.
 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 ******************************************************************************/

#ifndef LANGUAGE_H
#define LANGUAGE_H

#include "array.hpp"
#include "resource.hpp"
#include "space.hpp"

#include <moebius/tree_label.hpp>

using moebius::tree_label;

RESOURCE (language);

/******************************************************************************
 * The text property class
 ******************************************************************************/

#define TP_NORMAL 0
#define TP_HYPH 1
#define TP_THIN_SPACE 2
#define TP_SPACE 3
#define TP_DSPACE 4
#define TP_NB_THIN_SPACE 5
#define TP_NB_SPACE 6
#define TP_NB_DSPACE 7
#define TP_PERIOD 8
#define TP_CJK_NORMAL 9
#define TP_CJK_NO_BREAK 10
#define TP_CJK_PERIOD 11
#define TP_CJK_WIDE_PERIOD 12
#define TP_OPERATOR 13
#define TP_SHORTOP 14
#define TP_OTHER 15

#define SPC_NONE 0
#define SPC_THIN_SPACE 1
#define SPC_SPACE 2
#define SPC_DSPACE 3
#define SPC_PERIOD 4
#define SPC_TINY 5
#define SPC_CJK_NORMAL 6
#define SPC_CJK_PERIOD 7
#define SPC_CJK_WIDE_PERIOD 8
#define SPC_HALF 9
#define SPC_OPERATOR 10
#define SPC_WIDEOP 11
#define SPC_BIGOP 12
#define SPC_SHORT_APPLY 13
#define SPC_APPLY 14
#define SPC_MULTIPLY 15
#define SPC_MIDDLE 16
#define SPC_END_MARKER 17

#define HYPH_STD 10000
#define HYPH_PANIC 1000000
#define HYPH_INVALID 100000000

#define OP_UNKNOWN 0
#define OP_TEXT 1
#define OP_SKIP 2
#define OP_SYMBOL 3
#define OP_UNARY 4
#define OP_BINARY 5
#define OP_N_ARY 6
#define OP_PREFIX 7
#define OP_POSTFIX 8
#define OP_INFIX 9
#define OP_PREFIX_INFIX 10
#define OP_APPLY 11
#define OP_SEPARATOR 12
#define OP_OPENING_BRACKET 13
#define OP_MIDDLE_BRACKET 14
#define OP_CLOSING_BRACKET 15
#define OP_BIG 16
#define OP_TOTAL 17

#define LIMITS_NONE 0
#define LIMITS_DISPLAY 1
#define LIMITS_ALWAYS 2

struct text_property_rep {
  int type;
  int spc_before;
  int spc_after;
  int pen_before;
  int pen_after;

  int op_type;
  int priority;
  int limits;

  tree_label macro;

  text_property_rep (int type= TP_OTHER, int spc_before= SPC_NONE,
                     int spc_after= SPC_NONE, int pen_before= 0,
                     int pen_after= HYPH_INVALID, int op_type= OP_SYMBOL,
                     int priority= 1000, int limits= LIMITS_NONE,
                     tree_label macro= moebius::STRING);
};

text_property_rep          copy (text_property_rep tpr);
typedef text_property_rep* text_property;

/******************************************************************************
 * Possible successions of mathematical operators
 ******************************************************************************/

#define SUCCESSION_OK 0
#define REMOVE_SPACE_BEFORE 1
#define REMOVE_CURRENT_SPACE 2
#define REMOVE_ALL_SPACE 3

extern int succession_status_table[OP_TOTAL * OP_TOTAL];
inline int
succession_status (int op1, int op2) {
  return succession_status_table[op1 * OP_TOTAL + op2];
}
// int succession_status (int op1, int op2);
void init_succession_status_table ();

/******************************************************************************
 * The language structure
 ******************************************************************************/

struct language_rep : rep<language> {
  string                      lan_name; // name of the language
  int                         hl_lan;
  static hashmap<string, int> color_encoding;
  hashmap<int, string>        color_decoding;

  language_rep (string s);
  virtual text_property advance (tree t, int& pos)                    = 0;
  virtual array<int>    get_hyphens (string s)                        = 0;
  virtual void   hyphenate (string s, int after, string& l, string& r)= 0;
  virtual string get_group (string s);
  virtual array<string> get_members (string s);
  virtual void          highlight (tree t);
  virtual string        get_color (tree t, int start, int end);
};

array<string> get_supported_languages ();
language      text_language (string s);
language      math_language (string s);
language      prog_language (string s);
bool          prog_lang_exists (string s);
language      hyphenless_language (language base);
language      ad_hoc_language (language base, tree hyphs);

string        math_symbol_group (string s, string lan= "std-math");
array<string> math_group_members (string s, string lan= "std-math");
string        math_symbol_type (string s, string lan= "std-math");

void   initialize_color_decodings (string lan_name);
int    encode_color (string s);
string decode_color (string lan, int c);

void   spell_start ();
void   spell_done ();
string spell_start (string lan);
void   spell_done (string lan);
tree   spell_check (string lan, string s);
bool   check_word (string lan, string s);
void   spell_accept (string lan, string s, bool permanent= false);
void   spell_insert (string lan, string s);

#endif // defined LANGUAGE_H
